#include <iostream>
#include <string>

class Builder{
public:
    virtual void reset() = 0;
    virtual void setSeats(int number) = 0;
    virtual void setEngine(std::string engine) = 0;
    virtual void setGPS() = 0;
};

struct Car{
    int seatNumber = 0;
    std::string engine = "";
    bool withGPS = false;
    void printInfo()
    {
        std::cout<<"This Car has "<<seatNumber<<" seats, the engine is "<< engine;
        if(withGPS)
        {
            std::cout<<"with GPS"<<std::endl;
        } else{
            std::cout<<"without GPS"<<std::endl;
        }
    }
};

class CarBuilder : public Builder{
private:
    Car* pCar = nullptr;
public:
    void reset() override
    {
        pCar = new Car();
    }
    void setSeats(int number)override
    {
        pCar->seatNumber = number;
    }
    void setEngine(std::string engine)override
    {
        pCar->engine = engine;
    }
    void setGPS()override
    {
        pCar->withGPS = true;
    }
    Car* getResult()
    {
        return pCar;
    }
};

struct CarManual{
    int seatNumber = 0;
    std::string engine = "";
    bool withGPS = false;
    void printInfo()
    {
        std::cout<<"This CarManual: "<<std::endl;
        std::cout<<"seatNumber: "<< seatNumber<<std::endl;
        std::cout<<"engine: "<< engine<<std::endl;
        std::cout<<"GPS: ";
        if(withGPS)
        {
            std::cout<<"true"<<std::endl;
        } else{
            std::cout<<"false"<<std::endl;
        }
    }
};

class CarManualBuilder : public Builder{
private:
    CarManual *carManual = nullptr;
public:
    void reset() override
    {
        carManual = new CarManual();
    }
    void setSeats(int number)override
    {
        carManual->seatNumber = number;
    }
    void setEngine(std::string engine)override
    {
        carManual->engine = engine;
    }
    void setGPS()override
    {
        carManual->withGPS = true;
    }
    CarManual* getResult()
    {
        return carManual;
    }
};

class Director{
public:
    void makeSportsCar(Builder* builder)
    {
        builder->reset();
        builder->setSeats(2);
        builder->setEngine("SportEngine");
        builder->setGPS();
    }
    void makeSUVCar(Builder* builder)
    {
        builder->reset();
        builder->setSeats(4);
        builder->setEngine("SUVEngine");
    }
};

int main() {
    std::cout<<"build a sport car..."<<std::endl;
    Director* pD = new Director();
    CarBuilder *pCar = new CarBuilder();
    pD->makeSportsCar(pCar);
    Car* car = pCar->getResult();
    car->printInfo();
    std::cout<<"build a SUV car manual..."<<std::endl;
    CarManualBuilder *pCarM = new CarManualBuilder();
    pD->makeSUVCar(pCarM);
    CarManual* carManual = pCarM->getResult();
    carManual->printInfo();
    return 0;
}